﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

namespace FileDuplicateUtility
{
    /// <summary>
    /// Interaction logic for FilterSelector.xaml
    /// </summary>
    public partial class FilterSelector : UserControl
    {
        public FilterSelector()
        {
            InitializeComponent();

            SelectedFilter = AllFilter.Default;
        }

        public IEnumerable<Filter> AvailableFilters
        {
            get
            {
                yield return AllFilter.Default;
                yield return TextFilter.Default;
                yield return RegexFilter.Default;
            }
        }

        public Filter SelectedFilter
        {
            get { return (Filter)GetValue(SelectedFilterProperty); }
            set { SetValue(SelectedFilterProperty, value); }
        }

        public static readonly DependencyProperty SelectedFilterProperty =
            DependencyProperty.Register("SelectedFilter", typeof(Filter), typeof(FilterSelector), new UIPropertyMetadata(null));
    }

    public abstract class Filter : DependencyObject
    {
        public abstract string Name { get; }
        public virtual string Display { get { return Name; } }
        public virtual bool AllowMultiple { get { return true; } }

        public virtual Func<File, bool> Predicate
        {
            get { return x => true; }
        }

        public abstract Filter Copy();

        public virtual void Reset()
        {
            // do nothing
        }

        public virtual Filter Initialize()
        {
            return this;
        }

        public override string ToString()
        {
            return Name;
        }
    }

    public class AllFilter : Filter
    {
        public static readonly AllFilter Default = new AllFilter();

        public override string Name { get { return "All Items"; } }

        public override bool AllowMultiple { get { return false; } }

        public override Filter Copy()
        {
            return new AllFilter();
        }
    }

    public class TextFilter : Filter
    {
        public const string DefaultText = "";
        public static readonly TextFilter Default = null;

        static TextFilter()
        {
            Default = new TextFilter();
        }

        public TextFilter(string text = DefaultText)
        {
            SearchText = text;
        }

        public override string Name { get { return "Text Search"; } }
        public override string Display { get { return string.Format("{0}: {1}", Name, SearchText); } }

        private string Text { get; set; }

        public string SearchText
        {
            get { return (string)GetValue(SearchTextProperty); }
            set { SetValue(SearchTextProperty, value); }
        }

        public static readonly DependencyProperty SearchTextProperty =
            DependencyProperty.Register("SearchText", typeof(string), typeof(TextFilter), new UIPropertyMetadata(DefaultText));

        public override Func<File, bool> Predicate
        {
            get
            {
                return x => x.Name.Contains(Text);
            }
        }

        public override Filter Copy()
        {
            return new TextFilter(SearchText);
        }

        public override void Reset()
        {
            base.Reset();

            SearchText = DefaultText;
        }

        public override Filter Initialize()
        {
            Text = SearchText;

            return base.Initialize();
        }
    }

    public class RegexFilter : Filter
    {
        public const string DefaultPattern = ".";

        public static readonly RegexFilter Default = null;

        static RegexFilter()
        {
            Default = new RegexFilter();
        }

        public RegexFilter(string pattern = DefaultPattern)
        {
        }

        private Regex Regex { get; set; }

        public string Pattern
        {
            get { return (string)GetValue(PatternProperty); }
            set { SetValue(PatternProperty, value); }
        }

        public static readonly DependencyProperty PatternProperty =
            DependencyProperty.Register("Pattern", typeof(string), typeof(RegexFilter), new UIPropertyMetadata(DefaultPattern));

        public override string Name { get { return "Regex Pattern"; } }
        public override string Display { get { return string.Format("{0}: {1}", Name, Pattern); } }

        public override Func<File, bool> Predicate
        {
            get
            {
                return x => Regex.IsMatch(x.Name);
            }
        }

        public override Filter Copy()
        {
            return new RegexFilter(Pattern);
        }

        public override void Reset()
        {
            base.Reset();

            Pattern = DefaultPattern;
            Regex = null;
        }

        public override Filter Initialize()
        {
            Regex = new Regex(Pattern, RegexOptions.Compiled);

            return base.Initialize();
        }
    }
}
